# -*- coding: utf-8 -*-
#
# Copyright (c) 2011,2012 RMIT e-Research Office
#   (RMIT University, Australia)
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#    *  Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#    *  Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#    *  Neither the name of RMIT University nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""
.. module:: Bonza2
   :synopsis: Ingests the Bonza database into SMRA

.. moduleauthor:: Venki Balasubramanian <Venki Balasubramanian@rmit.edu.au>


"""

import pymysql 
import logging
from django.conf import settings
from smra.smra_portal.models import ParameterName

from django.utils.http import urlquote_plus


from smra.smra_portal.models import System
from smra.smra_portal.ReposPlugin import InvalidConfigurationException 
from smra.smra_portal.models import Repository



logger = logging.getLogger(__name__)


class ReposConverter(object):
    """ Connects to the BONZA repository, extracts data either through
    HTML scraping, direct connection to a database or some other API, and then
    parses it and finally calls create_media_object to insert into the SMRA model""" 
    
    
    
    REPOS_NAME = "BONZA"    
    ns = "http://smra.edu.au/smra/bonza2"  
    
      
    
     
    
    def ingest(self,rp,system):
        """ Convert the data on the BONZA website into form that can be added 
        to models"""
        
        try:
            sys = System.objects.get(name=system)
        except System.DoesNotExist():
            raise InvalidConfigurationException("Missing System definition for %s" % system)
        logger.debug("REPOS_NAME = %s" % self.REPOS_NAME)
        try:
            self.repos = Repository.objects.get(name=self.REPOS_NAME, system=sys)
        except Repository.DoesNotExist:
            self.repos = Repository()
            self.repos.name = self.REPOS_NAME
            self.repos.system = sys
            self.repos.save()
        
        if settings.BONZAPASS:
            conn = pymysql.connect(host=settings.BONZAHOST, port=settings.BONZAPORT, user=settings.BONZAUSER, 
                               passwd=settings.BONZAPASS, db=settings.BONZADB)
        else:
            conn = pymysql.connect(host=settings.BONZAHOST, port=settings.BONZAPORT, user=settings.BONZAUSER, 
                             db=settings.BONZADB)
        cur = conn.cursor()
#       cur.execute("SELECT id,release_title,copyright_title,"
#                    "alternative_title,production_year, "
#                    "first_release_year,description, "
#                    "synopsis FROM production")
        
#       cur.execute("SELECT pd.id, pd.release_title,pd.alternative_title,pd.production_year,"
#                   'first_release_year, pd.synopsis,CONCAT(ps.first_name," ",ps.family_name),' 
#                   "ps.birth_year, ps.death_year, ps.description, c.name, c.description, c.town " 
#                   "FROM production AS pd " 
#                   'LEFT JOIN role_link AS rl ON ( pd.id = rl.record_id AND rl.roletype_id = "62") '
#                   "LEFT JOIN person AS ps ON (rl.person_id = ps.id ) " 
#                   "LEFT JOIN roletype AS r ON (r.id = rl.roletype_id) "  
#                   "LEFT JOIN company AS c ON (c.id = rl.company_id) LIMIT 5" ) 
        
   #  Production data from BONZA     

        cur.execute("SELECT pd.id, pd.release_title, pd.synopsis,"
                    'CONCAT(r.description, " : ",ps.first_name," ",ps.family_name),' 
                    "rt.record_type,c.name,pd.alternative_title,pd.description,n.content,pd.production_year,"
                    "pd.first_release_year, r.description " 
                    "FROM production AS pd " 
                    "LEFT JOIN record_type AS rt ON (rt.id = pd.record_type_id)"
                    "LEFT JOIN role_link AS rl ON (pd.id = rl.record_id)"
                    "LEFT JOIN person    AS ps ON (rl.person_id = ps.id )" 
                    "LEFT JOIN roletype  AS r  ON (r.id = rl.roletype_id)" 
                    "LEFT JOIN company   AS c  ON (c.id = rl.company_id)" 
                    "LEFT JOIN (entity_role_links AS erl, production_cinema AS pc) ON (erl.a_record_id = pd.id AND erl.id = pc.entity_link_id)" 
                    "LEFT JOIN cinema_details AS cd ON (pd.id = erl.a_record_id AND cd.id = erl.b_record_id)"  
                    "LEFT JOIN note as n ON (n.record_type_id = erl.b_record_type_id AND n.id = erl.b_record_id) " ) 


        recordset ={}
        
        for (id,release_title,synopsis,responsibility,type,company_name,alternative_title,comment,note,production_year,
              first_release_year,person_role)  in cur:
            
 #          print "%s %s %s" % (id,release_title, person_role)       
             
            id = 'P' + str(id)  
            if id in recordset.keys():
                             
                a[2] = str(a[2]) + "," + str(responsibility)
                if (person_role == 'Journal') :  
                    a[5] = company_name        # 4 Journal

                if (person_role == 'Newspaper') : 
                    a[6] = company_name        # 5 Newspaper

                recordset[id] = a
            else:
                            
                if len(recordset) != 0 :
                   self.create_bonza_object_prod(rp,recordset.keys()[0],recordset[recordset.keys()[0]])
                   recordset={}
                              
                a=[]
                a.insert(0,release_title)      # 0 Title
                a.insert(1,synopsis)           # 1 Summary 
                a.insert(2,responsibility)     # 2 Responsibility
                a.insert(3,'Bonza')
                a.insert(4,type)                 # 4 Type
                if (person_role == 'Journal') :  
                    a.insert(5,company_name)     # 5 Journal
                else:
                    a.insert(5,'')               # 5 
                    
                if (person_role == 'Newspaper') : 
                    a.insert(6,company_name)     # 6 Newspaper
                else:
                    a.insert(6,'')               # 6 
                
                a.insert(7,alternative_title)    # 7 Alternate Title
                a.insert(8,comment)              # 8 Comment
                a.insert(9,note)                 # 9 Notes
                a.insert(10,production_year)      # 10 Production Year
                a.insert(11,first_release_year)   # 11 First Release Year 
    
                recordset[id] = a
                       
            # If the record is missing in BONZA then it will not be 
            # returned and the SMRA will be unchanged.  FIXME: need 
            # some way for BONZA to indicate that a record has been
            # deleted and therefore should also be deleted in SMRA
            # There may be a field in the BONZA schema that indicates 
            # this.

        if len(recordset) != 0 :
            self.create_bonza_object_prod(rp,recordset.keys()[0],recordset[recordset.keys()[0]])
            recordset={}                   
        cur.close()
        
        # Bibilography data ingestion starts here
        cur = conn.cursor()     
        cur.execute(                    
                    "SELECT bg.id,bg.title,bg.subtitle,bg.synopsis,r.description,"
                    'CONCAT(ps.first_name," ",ps.family_name),' 
                    "bg.publication_date,c.name,bgt.description,bg.issue,bg.page_number,bg.volume,bg.description "
                    "FROM   bibliography   AS bg " 
                    "LEFT JOIN bibliotype  AS bgt ON (bg.bibliotype_id = bgt.id) "
                    "LEFT JOIN role_link AS rl ON (bg.id = rl.record_id AND rl.linktype_id = bg.record_type_id) "
                    "LEFT JOIN person    AS ps ON (rl.person_id = ps.id ) " 
                    "LEFT JOIN roletype  AS r  ON (r.id = rl.roletype_id) " 
                    "LEFT JOIN company   AS c  ON (c.id = rl.company_id) "
                    )  

        recordset ={}
        
        for (id,title,subtitle,summary,person_role,person_name,publication_date,
             company_name,type,issue,page_number,volume,comments) in cur:    
            
            id = 'B' + str(id)  
        
            if id in recordset.keys():
                             
                if (person_role == 'Author') :
                   a[4] = person_name                      # 4 Author
                   
                if (person_role == 'Publisher') :
                   a[6] = company_name                     # 5 Publisher
                
                if (person_role == 'Journal') :
                   a[10] = company_name                    # 10 Journal  
                                  
                if (person_role == 'Newspaper') :
                   a[13] = company_name                    # 13 Newspaper
            else:
                if len(recordset) != 0 :
                   self.create_bonza_object_bib(rp,recordset.keys()[0],recordset[recordset.keys()[0]])
                   recordset={}
                              
                a=[]
                a.insert(0,title)              # 0 Title
                a.insert(1,subtitle)           # 1 Subtitle 
                a.insert(2,summary)           # 2 Summary 
                a.insert(3,'')                 # 3 Responsibility
                
                if (person_role == 'Author') :
                   a.insert(4,person_name)     # 4 Author
                else:
                   a.insert(4,'')
                   
                a.insert(5,str(publication_date))            # 5 Publication Date

                if (person_role == 'Publisher') :
                   a.insert(6,company_name)                # 6 Publisher
                else:
                   a.insert(6,'')
                       
                a.insert(7,'Bonza')
                a.insert(8,type)
                a.insert(9,issue)
                
                if (person_role == 'Journal') :
                   a.insert(10,company_name)               
                else:
                   a.insert(10,'')    
                                  
                a.insert(11,page_number)
                a.insert(12,volume)
                if (person_role == 'Newspaper') :
                   a.insert(13,company_name)               
                else:
                   a.insert(13,'')    
                
                a.insert(14,comments)
    
                recordset[id] = a
        
 
        if len(recordset) != 0 :
            self.create_bonza_object_bib(rp,recordset.keys()[0],recordset[recordset.keys()[0]])
            recordset={}                   
        cur.close()
        
        conn.close()
        
        return "Hello from BONZA plugin"



    def create_bonza_object_prod(self,rp,id,a):
        
  #     print "%s %s %s" % (id,a[0],a[1])    
        
        schemalist = ['Title','Summary','Responsibility','Collection','Type']  
        extendedlist = ['Journal','Newspaper','Alternate Title','Comment', 'Notes', 'Production Year', 'First Release Year'] 
 
        basedic ={}
        extdisc ={}
        
        i=0
        for item in schemalist:
            if a[i]: 
               basedic[item] = a[i]
               i+=1
            else:
               i+=1
        
        logger.debug("basedic=%s" %basedic)
        
        for item in extendedlist:
            if a[i]: 
               extdisc[item] = a[i]
               i+=1
            else:
               i+=1 
        
        logger.debug("extdisc=%s" % extdisc)
        
               
        obj = rp.create_media_object(repos_name="BONZA",ident=id,description=a[0],
                             metadata=(                                  
                               ( 
                                ('http://rmit.edu.au/schemas/smra',
                                'base'), basedic
                                ),
                              ))     
             
        rp.set_last_ingested_metadata(obj=obj,repos_name="BONZA", 
                              metadata=(                                  
                               ( 
                                ('http://rmit.edu.au/schemas/smra',
                                'extended'), extdisc
                                ),
                              ))  

        self._add_aux_metadata(rp, obj, id, "production", a[0])
      

    def create_bonza_object_bib(self,rp,id,a):
        
  #     print "%s %s %s" % (id,a[0],a[1])     
               
        schemalist = ['Title','Subtitle','Summary','Responsibility','Author','Publication Date', 'Publisher','Collection','Type']      
        extendedlist = ['Issue','Journal', 'Page', 'Volume', 'Newspaper','Comment']
        
        basedic ={}
        extdisc ={}
        
        i=0
        for item in schemalist:
            if a[i]: 
               basedic[item] = a[i]
               i+=1
            else:
               i+=1
        
        logger.debug("basedic=%s" %basedic)
        
        for item in extendedlist:
            if a[i]: 
               extdisc[item] = a[i]
               i+=1
            else:
               i+=1 
        
        logger.debug("extdisc=%s" % extdisc)

       
        obj = rp.create_media_object(repos_name="BONZA",ident=id,description=a[0],
                             metadata=(                                  
                               ( 
                                ('http://rmit.edu.au/schemas/smra',
                                'base'),basedic                                 
                                ),
                              ))     
             
        rp.set_last_ingested_metadata(obj=obj,repos_name="BONZA", 
                              metadata=(                                  
                               ( 
                                ('http://rmit.edu.au/schemas/smra',
                                'extended'), extdisc                            
                                ),
                              ))  
        
        
        self._add_aux_metadata(rp, obj, id, "bibliography",a[0])
        
    
        


    def _add_aux_metadata(self, rp, obj, id, database, desc):
        
        final_data = []
        final_datas = []
        final_data.append(("http://rmit.edu.au/schemas/smra","system"))
        final_data.append({'ID':id[1:]})
        final_datas.append(final_data)        
        rp.set_last_ingested_metadata(obj=obj,repos_name="BONZA", 
                              metadata=final_datas)
        
        
        bonza_link = "http://bonza.rmit.edu.au/%s/view/%s" % (database, id[1:])
        final_data = []
        final_datas = []
        final_data.append(("http://rmit.edu.au/schemas/smra","external"))
        final_data.append({'IMDB':'http://www.imdb.com/find?s=all&q=%s'
                                         % urlquote_plus(desc),
                            'Link to Original Record':bonza_link})
        final_datas.append(final_data)      
        rp.set_last_ingested_metadata(obj=obj,repos_name="BONZA", 
                              metadata=final_datas)  
        
        
    
    def setup_schemas(self,repos_plugin):
        """
        Given statistics about Records types and used attributes in the MAYER
        database, creates schemas in the SMRA.

        Note: Warning: this function is NOT reinterant, as it will create 
        additional MAYER schemas for each run.  Use with caution
        
        Copied from Mayer.py changed it to suit BONZA
        """
        
        
        schemas = (('Title',ParameterName.STRING,90,""),
                   ('Subtitle',ParameterName.STRING,85,""),
                   ('Subject',ParameterName.STRING,80,""),
                   ('Summary',ParameterName.STRING,75,""),
                   ('Responsibility',ParameterName.STRING,70,""),
                   ('ISBN_ISSN',ParameterName.STRING,65,""), #check underscore
                   ('Author',ParameterName.STRING,60,""),
                   ('Publication Date',ParameterName.STRING,55,""),
                   ('Publisher',ParameterName.STRING,50,""),
                   ('Contents',ParameterName.STRING,45,""),
                   ('Physical Description',ParameterName.STRING,40,""),
                   ('Source',ParameterName.STRING,35,""),
                   ('Collection',ParameterName.STRING,30,""),
                   ('Type',ParameterName.STRING,25,""))

        repos_plugin.create_schema(ns="http://rmit.edu.au/schemas/smra",
                            name="base",
                            desc="Details",
                            parameters=schemas)

        schemas = (('Issue',ParameterName.STRING,90,""),
                   ('Journal',ParameterName.STRING,85,""),
                   ('Page',ParameterName.STRING,80,""),
                   ('Volume',ParameterName.NUMERIC,75,""),
                   ('Newspaper',ParameterName.STRING,70,""),
                   ('Performer',ParameterName.STRING,65,""),
                   ('Alternate Title',ParameterName.STRING,60,""),
                   ('Product Code',ParameterName.STRING,55,""),
                   ('Credits',ParameterName.STRING,50,""),
                   ('Donation',ParameterName.STRING,45,""),
                   ('Language',ParameterName.STRING,40,""),
                   ('Comment',ParameterName.STRING,35,""),
                   ('Notes',ParameterName.STRING,30,""),
                   ('Production Year',ParameterName.YEAR,25,""),
                   ('First Release Year',ParameterName.YEAR,20,""))

        repos_plugin.create_schema(ns="http://rmit.edu.au/schemas/smra",
                            name="extended",
                            desc="Extended Details",
                            parameters=schemas)

        schemas = (('Record Type',ParameterName.STRING,90,""),
                   ('Created',ParameterName.DATE,80,""),
                   ('ID',ParameterName.STRING,75,""),
                   ('Call No',ParameterName.STRING,70,""))

        repos_plugin.create_schema(ns="http://rmit.edu.au/schemas/smra",
                            name="system",
                            desc="System Details",
                            parameters=schemas)

        
        #TODO: this schema could be created in ReposPlugin
        schemas  = (('IMDB',
                    ParameterName.LINK,90,""),
                   ('Link to Original Record',ParameterName.LINK,80,""))
       
        repos_plugin.create_schema(ns="http://rmit.edu.au/schemas/smra",
                            name="external",
                            desc="External Collections",
                            parameters=schemas)
        
        
        
        

#        schemas = (('ID',ParameterName.STRING,0,""),
#                   ('CL',ParameterName.STRING,0,""),
#                   ('Title',ParameterName.STRING,0,""),
#                   ('SER',ParameterName.STRING,0,""),
#                   ('ED',ParameterName.STRING,0,""),
#                   ('AU',ParameterName.STRING,0,""),
#                   ('PL',ParameterName.STRING,0,""),
#                   ('PUB',ParameterName.STRING,0,""),
#                   ('DT',ParameterName.STRING,0,""),
#                   ('PD',ParameterName.STRING,0,""),
#                   ('DE',ParameterName.STRING,0,""),
#                   ('BN',ParameterName.STRING,0,""),
#                   ('SN',ParameterName.STRING,0,""),
#                   ('CPS',ParameterName.STRING,0,""),
#                   ('PRE',ParameterName.STRING,0,""),
#                   ('NTS',ParameterName.STRING,0,""),
#                   ('OK',ParameterName.STRING,0,""),
#                   ('Creation Date',ParameterName.DATE,0,""),                   
#                   ('Corporate Author',ParameterName.STRING,0,""),                   
#                   ('Responsibility',ParameterName.STRING,0,""),                   
#                   ('Summary',ParameterName.STRING,0,""),
#                   ('Subtitle',ParameterName.STRING,0,""))
#       
#        repos_plugin.create_schema(ns=self.ns,
#                            name="item",
#                            desc="Mayer Item",
#                            parameters=schemas)
            
        repos_plugin.create_schema(ns="http://smra.edu.au/smra/ingest",
                            name="metadata",
                            desc="Metadata",
                            parameters=[("Last Ingested",
                                         ParameterName.DATE,
                                         0,
                                         "")])
